import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from PIL import Image, ImageTk
from pathlib import Path

class LicensePlateApp:
    def __init__(self, root):
        self.root = root
        self.root.title("车牌识别系统 v1.0")
        self.root.geometry("900x700")

        # 图片引用保持
        self.original_photo = None
        self.processed_photo = None

        # 样式配置
        self.style = ttk.Style()
        self.style.configure('TButton', font=('Microsoft YaHei', 10))
        self.style.configure('TLabel', font=('Microsoft YaHei', 10))

        # 主框架
        self.main_frame = ttk.Frame(root)
        self.main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        # 控制面板
        self.control_frame = ttk.Frame(self.main_frame)
        self.control_frame.pack(fill=tk.X, pady=10)

        self.upload_btn = ttk.Button(
            self.control_frame,
            text="上传图片",
            command=self.upload_file,
            width=15
        )
        self.upload_btn.pack(side=tk.LEFT, padx=5)

        self.detect_btn = ttk.Button(
            self.control_frame,
            text="识别车牌",
            command=self.detect_plate,
            width=15
        )
        self.detect_btn.pack(side=tk.LEFT, padx=5)

        # 结果显示区域
        self.result_frame = ttk.Frame(self.main_frame)
        self.result_frame.pack(fill=tk.BOTH, expand=True)

        # 原图区域
        self.original_frame = ttk.LabelFrame(self.result_frame, text="原始图片")
        self.original_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5)

        self.original_canvas = tk.Canvas(self.original_frame, bg="white")
        self.original_canvas.pack(fill=tk.BOTH, expand=True)

        # 处理结果区域
        self.processed_frame = ttk.LabelFrame(self.result_frame, text="识别结果")
        self.processed_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5)

        self.processed_canvas = tk.Canvas(self.processed_frame, bg="white")
        self.processed_canvas.pack(fill=tk.BOTH, expand=True)

        # 识别文本结果（添加滚动条）
        self.text_frame = ttk.LabelFrame(self.main_frame, text="车牌号码")
        self.text_frame.pack(fill=tk.X, pady=10)

        self.text_scroll = ttk.Scrollbar(self.text_frame)
        self.text_scroll.pack(side=tk.RIGHT, fill=tk.Y)

        self.result_text = tk.Text(
            self.text_frame,
            height=3,
            font=('Microsoft YaHei', 14),
            wrap=tk.WORD,
            yscrollcommand=self.text_scroll.set
        )
        self.result_text.pack(fill=tk.BOTH, expand=True)
        self.text_scroll.config(command=self.result_text.yview)

        # 状态栏
        self.status_var = tk.StringVar()
        self.status_var.set("就绪")
        self.status_bar = ttk.Label(
            root,
            textvariable=self.status_var,
            relief=tk.SUNKEN,
            anchor=tk.W
        )
        self.status_bar.pack(fill=tk.X, side=tk.BOTTOM)

        # 变量初始化
        self.uploaded_image_path = None
        self.processed_image_path = None
        self.plate_texts = []

    def upload_file(self):
        file_types = [
            ("图片文件", "*.jpg *.jpeg *.png *.bmp"),
            ("所有文件", "*.*")
        ]
        file_path = filedialog.askopenfilename(title="选择图片", filetypes=file_types)

        if file_path:
            self.uploaded_image_path = file_path
            self.show_image(file_path, self.original_canvas, is_original=True)
            self.status_var.set(f"已加载: {Path(file_path).name}")
            self.result_text.delete(1.0, tk.END)

    def detect_plate(self):
        if not self.uploaded_image_path:
            messagebox.showwarning("警告", "请先上传图片！")
            return

        self.status_var.set("正在识别...")
        self.root.update()  # 强制更新UI

        try:
            from test import run_inference
            processed_path, plate_results = run_inference(self.uploaded_image_path)

            if processed_path:
                self.processed_image_path = processed_path
                self.show_image(processed_path, self.processed_canvas, is_original=False)

                # 显示识别结果
                self.result_text.delete(1.0, tk.END)
                if plate_results:
                    for result in plate_results:
                        self.result_text.insert(tk.END,
                                                f"车牌类型: {result['type']}\n"
                                                f"车牌号码: {result['text']}\n"
                                                f"置信度: {result['confidence']:.2f}\n"
                                                "------------------------\n")
                else:
                    self.result_text.insert(tk.END, "未识别到车牌")
                self.status_var.set("识别完成")
            else:
                messagebox.showerror("错误", "未能生成处理后的图片")
                self.status_var.set("识别失败")

        except Exception as e:
            messagebox.showerror("错误", f"识别过程中出错:\n{str(e)}")
            self.status_var.set(f"错误: {str(e)}")

    def show_image(self, path, canvas, is_original):
        try:
            image = Image.open(path)
            canvas_width = canvas.winfo_width() or 400
            canvas_height = canvas.winfo_height() or 300

            # 计算缩放比例
            img_ratio = image.width / image.height
            canvas_ratio = canvas_width / canvas_height

            if img_ratio > canvas_ratio:
                new_width = canvas_width
                new_height = int(canvas_width / img_ratio)
            else:
                new_height = canvas_height
                new_width = int(canvas_height * img_ratio)

            image = image.resize((new_width, new_height), Image.Resampling.LANCZOS)

            # 保存图片引用
            if is_original:
                self.original_photo = ImageTk.PhotoImage(image)
                img_ref = self.original_photo
            else:
                self.processed_photo = ImageTk.PhotoImage(image)
                img_ref = self.processed_photo

            canvas.delete("all")
            canvas.create_image(
                canvas_width // 2,
                canvas_height // 2,
                anchor=tk.CENTER,
                image=img_ref
            )
        except Exception as e:
            messagebox.showerror("错误", f"无法显示图片:\n{str(e)}")


if __name__ == "__main__":
    root = tk.Tk()
    app = LicensePlateApp(root)
    root.mainloop()
